package com.rederxu.views;

import java.util.zip.Inflater;

import com.rederxu.farmer.R;
import com.rederxu.tools.DisplayUtils;
import com.rederxu.tools.MathUtils;
import com.rederxu.tools.StringUtils;

import android.widget.AbsListView.OnScrollListener;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class XListView extends ListView implements OnTouchListener,OnScrollListener{

	private LayoutInflater inflater = null;
	private View headerView = null;
	private View footerView = null;
	private float moveDownHeight = 0;
	private final float HEIGHT_HEADER_TO_MENTION = DisplayUtils.dipToPx(getContext(), 120);
	private final float HEIGHT_HEADER_TO_REFRESH = DisplayUtils.dipToPx(getContext(), 140);
	private final String TIP_HEADER_GO_ON = "继续下拉刷新";
	private final String TIP_HEADER_REFRESH = "放手刷新";
	private final String TIP_HEADER_REFRESHING = "正在刷新";
	private onXListViewActionListener listener = null;
	private boolean isLoadingMore = false;
	private boolean refreshEnable = true;
	private boolean loadMoreEnable = true;
	private boolean touching = false;
	
	public XListView(Context context) {
		super(context);
		init(context);
	}

	public XListView(Context context, AttributeSet attrs, int defStyleAttr,
			int defStyleRes) {
		super(context, attrs, defStyleAttr, defStyleRes);
		init(context);
	}

	public XListView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context);
	}

	public XListView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	private void init(Context context){
		inflater = LayoutInflater.from(context);
		headerView = inflater.inflate(R.layout.header_view_xlistview_farmer,null);
		footerView = inflater.inflate(R.layout.footer_view_xlistview_farmer, null);
		this.addHeaderView(headerView);
		this.addFooterView(footerView);
		this.setOnTouchListener(this);
		this.setOnScrollListener(this);
		updateHeaderHeight(0);
		
		Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_right_farmer);
		LayoutAnimationController lac = new LayoutAnimationController(animation);
		lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
		lac.setDelay(0.4f);
		this.setLayoutAnimation(lac);
	}
	
	private void updateHeaderHeight(float height){
		android.view.ViewGroup.LayoutParams lp = headerView.getLayoutParams();
		if(lp != null){
			lp.height = (int)height;
			headerView.setLayoutParams(lp);
		}
	}

	private int getHeaderHeight(){
		android.view.ViewGroup.LayoutParams lp = headerView.getLayoutParams();
		return lp.height;
	}
	
	private void setHeaderTip(String tip){
		TextView tipView = (TextView)headerView.findViewById(R.id.tv_refresh_tip_header);
		tipView.setText(tip);
	}
	
	private String getHeaderTip(){
		TextView tipView = (TextView)headerView.findViewById(R.id.tv_refresh_tip_header);
		return tipView.getText().toString();
	}
	
	private void aniHeaderNormalToRefresh(){
		RotateAnimation animation = new RotateAnimation(0,180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		animation.setDuration(200);
		animation.setFillAfter(true);
		headerView.findViewById(R.id.ic_refresh_header).startAnimation(animation);
	}
	
	private void aniHeaderRefreshToNormal(){
		RotateAnimation animation = new RotateAnimation(180,359,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		animation.setDuration(200);
		animation.setFillAfter(true);
		headerView.findViewById(R.id.ic_refresh_header).startAnimation(animation);
	}
	
	private void aniHeaderRefreshing(){
		RotateAnimation animation = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		animation.setDuration(800);
		animation.setInterpolator(new LinearInterpolator());//不停顿 
		animation.setRepeatCount(100000);
		ImageView ic = (ImageView) headerView.findViewById(R.id.ic_refresh_header);
		ic.setImageResource(R.drawable.default_ptr_rotate);
		ic.startAnimation(animation);
	}
	
	private void aniFooterLoadingMore(){
		RotateAnimation animation = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		animation.setDuration(1000);
		animation.setInterpolator(new LinearInterpolator());//不停顿 
		animation.setRepeatCount(1000000);
		ImageView ic = (ImageView) footerView.findViewById(R.id.ic_loadmore_header);
		ic.startAnimation(animation);
	}
	
	@Override
	public void setAdapter(ListAdapter adapter) {
		super.setAdapter(adapter);
		updateHeaderHeight(0);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if(!refreshEnable || getHeaderTip().equalsIgnoreCase(TIP_HEADER_REFRESHING)){
			return false;
		}
		switch(event.getAction()){
		case MotionEvent.ACTION_DOWN:
			moveDownHeight = 0;
			touching = true;
			break;
		case MotionEvent.ACTION_UP:
			touching = false;
			if(getHeaderTip().equalsIgnoreCase(TIP_HEADER_REFRESH)){
				updateHeaderHeight((float)DisplayUtils.dipToPx(getContext(), 40));
				aniHeaderRefreshing();
				setHeaderTip(TIP_HEADER_REFRESHING);
				if(listener != null){
					listener.onRefresh();
				}
			}else{
				headerView.setVisibility(View.GONE);
				updateHeaderHeight(0);
				if(this.getFirstVisiblePosition() == 0){
					try{
						setSelection(1);
					}catch(Exception e){
						
					}
				}
			}
			break;
		case MotionEvent.ACTION_MOVE:
			if(this.getFirstVisiblePosition() == 0){
				headerView.setVisibility(View.VISIBLE);
				if(moveDownHeight == 0){
					moveDownHeight = event.getY();
					return false;
				}
				int height = getHeaderHeight();
				float newMovedY = event.getY() - moveDownHeight;
				if(height < HEIGHT_HEADER_TO_MENTION){
					moveDownHeight = event.getY();
					updateHeaderHeight(height + newMovedY);
					if(getHeaderTip().equalsIgnoreCase(TIP_HEADER_REFRESH)){
						aniHeaderRefreshToNormal();
					}
					setHeaderTip(TIP_HEADER_GO_ON);
				}else if(height >= HEIGHT_HEADER_TO_MENTION && height < HEIGHT_HEADER_TO_REFRESH){
					newMovedY /= 15;
					moveDownHeight = event.getY();
					updateHeaderHeight(height + newMovedY);
					if(getHeaderTip().equalsIgnoreCase(TIP_HEADER_GO_ON)){
						aniHeaderNormalToRefresh();
					}
					setHeaderTip(TIP_HEADER_REFRESH);
				}
			}
			break;
		}
		return false;
	}
	
	public void setXListViewListener(onXListViewActionListener l){
		this.listener = l;
	}
	
	public void setRefreshEnable(boolean enable){
		this.refreshEnable = enable;
		if(enable == false){
			this.removeHeaderView(headerView);
		}
	}
	
	public void setLoadMoreEnable(boolean enable){
		this.loadMoreEnable = enable;
		if(enable == false){
			this.removeFooterView(footerView);
		}
	}
	
	public void refreshOver(){
		ImageView ic = (ImageView) headerView.findViewById(R.id.ic_refresh_header);
		ic.setImageResource(R.drawable.indicator_arrow);
		setHeaderTip(TIP_HEADER_GO_ON);
		setSelection(1);
		String refreshTime = MathUtils.timeFormat(System.currentTimeMillis());
		setRefreshTime(refreshTime);
	}

	public void setRefreshTime(String timeFormated){
		TextView time = (TextView) headerView.findViewById(R.id.tv_time_tip_header);
		time.setText("上次刷新：" + timeFormated);
	}
	
	public void loadMoreOver(){
		isLoadingMore = false;
	}
	
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		if(loadMoreEnable && firstVisibleItem + visibleItemCount == totalItemCount && listener != null && !isLoadingMore){
			listener.onLoadmore();
			isLoadingMore = true;
			aniFooterLoadingMore();
		}else if(refreshEnable && !touching && firstVisibleItem == 0){
			setSelection(1);
		}
	}
}
